#ifndef RAIN_H_91F3HH90
#define RAIN_H_91F3HH90

#include "raindrop.h"
#include "util/color4f.h"
#include "util/vec3f.h"
#include <list>

class Rain {
private:
    list<RainDrop*> myRainDrops;
    /* Drops to generate per frame */
    GLint myRainDropsPerFrame;
    /* x, y, z values of size of area */
    Vec3f myGenAxesArea;
    /* Center of rain generating area */
    Vec3f *myGenCenter;
    
    Color4f *myRainColor;
    
public:
    static const GLfloat Y_DISPLAY_THRESHOLD = -10;
    
    Rain (GLint dropsPerFrame, Vec3f &centerPos, Vec3f axesAreaVec, Color4f *rainColor=NULL) {
        myRainDropsPerFrame = dropsPerFrame;
        myGenCenter = &centerPos; 
        myGenAxesArea = axesAreaVec;
        if (rainColor == NULL) {
            myRainColor = new Color4f(0.3, 0.3, 0.5, 0.2);
        } else {
            myRainColor = rainColor;
        }
    }
    
    virtual ~Rain () {
        delete myRainColor;
    }
    
    void draw() {
        glEnable(GL_BLEND);
        // glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        glPushMatrix();
            glLineWidth(0.1);
            // glColor4f((*myRainColor)[0], (*myRainColor)[1], (*myRainColor)[2], (*myRainColor)[3]);
            // Draw all raindrops owned by this cloud
            list<RainDrop*>::iterator it;
            for (it = myRainDrops.begin(); it != myRainDrops.end(); it++) {
                (*it)->draw();
            }
        glPopMatrix();
        glDisable(GL_BLEND);
    }
    
    void update() {
        // Update all raindrops
        list<RainDrop*>::iterator it;
        for (it = myRainDrops.begin(); it != myRainDrops.end(); ) {
            // Delete raindrop if y value too low, i.e. off the screen
            RainDrop *rainDrop = *it; // rainDrop is pointer to raindrop object
            if (rainDrop->getYPos() < Y_DISPLAY_THRESHOLD) {
                delete rainDrop;
                it = myRainDrops.erase(it);
            } else {
                rainDrop->update();
                it++;
            }
        }
        
        generateRain();
    }

    void setRainColor(Color4f *newColor) {
        myRainColor = newColor;
    }

private:
    void generateRain() {
        Vec3f center = *myGenCenter;
        // find random location within cloud's body and create rain from there
        for(int i = 0; i < myRainDropsPerFrame; i++) {
            Vec3f rainDropPos;
            for(size_t coord = 0; coord < 3; ++coord) {
                GLfloat range = myGenAxesArea[coord]/2;
                rainDropPos[coord] = randFloatRange(center[coord] + range, 
                                                    center[coord] - range);
            }
            RainDrop *drop;
            drop = new RainDrop(rainDropPos, myRainColor);
            myRainDrops.push_back(drop);
        }
    }
};

#endif /* end of include guard: RAIN_H_91F3HH90 */
